from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_jwt_extended import JWTManager
from flask_cors import CORS
from flask_migrate import Migrate
from flask_marshmallow import Marshmallow
import os
from datetime import timedelta
from dotenv import load_dotenv

# 加载环境变量
load_dotenv()

# 初始化扩展
db = SQLAlchemy()
jwt = JWTManager()
migrate = Migrate()
ma = Marshmallow()

def create_app(config_name=None):
    """应用工厂函数"""
    app = Flask(__name__)
    
    # 禁用URL重定向，避免丢失Authorization头部
    app.url_map.strict_slashes = False
    
    # 配置加载
    if config_name is None:
        config_name = os.getenv('FLASK_ENV', 'development')
    
    if config_name == 'production':
        app.config.from_object('app.config.ProductionConfig')
    elif config_name == 'testing':
        app.config.from_object('app.config.TestingConfig')
    else:
        app.config.from_object('app.config.DevelopmentConfig')
    
    # 初始化扩展
    db.init_app(app)
    jwt.init_app(app)
    migrate.init_app(app, db)
    ma.init_app(app)
    
    # JWT错误处理
    @jwt.expired_token_loader
    def expired_token_callback(jwt_header, jwt_payload):
        print(f"❌ Token已过期: {jwt_payload}")
        return {'message': 'Token已过期'}, 401
    
    @jwt.invalid_token_loader
    def invalid_token_callback(error):
        print(f"❌ Token无效: {error}")
        return {'message': f'Token无效: {error}'}, 401
    
    @jwt.unauthorized_loader
    def missing_token_callback(error):
        print(f"❌ 缺少Authorization头部: {error}")
        # 打印请求信息以便调试
        from flask import request
        print(f"请求URL: {request.url}")
        print(f"请求方法: {request.method}")
        print(f"请求头: {dict(request.headers)}")
        return {'message': '缺少Authorization头部'}, 401
    
    # 配置CORS
    CORS(app, resources={
        r"/api/*": {
            "origins": ["http://localhost:3000", "http://localhost:5173"],
            "methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
            "allow_headers": ["Content-Type", "Authorization"]
        }
    })
    
    # 请求日志中间件
    # @app.before_request
    # def log_request():
    #     from flask import request
    #     print(f"\n🔍 收到请求:")
    #     print(f"  URL: {request.url}")
    #     print(f"  方法: {request.method}")
    #     print(f"  Authorization: {request.headers.get('Authorization', '未设置')}")
    #     print(f"  Content-Type: {request.headers.get('Content-Type', '未设置')}")
    #     print(f"  所有请求头: {dict(request.headers)}")
    
    # 注册蓝图
    from app.api.auth import auth_bp
    from app.api.users import users_bp
    from app.api.roles import roles_bp
    from app.api.permissions import permissions_bp
    from app.api.menus import menus_bp
    from app.api.stats import stats_bp
    from app.api.regulation_services import regulation_services_bp
    from app.api.gep_parameters import gep_parameters_bp
    from app.api.gep_results import gep_results_bp
    from app.api.vep_parameters import vep_parameters_bp
    from app.api.vep_results import vep_results_bp
    
    app.register_blueprint(auth_bp, url_prefix='/api/auth')
    app.register_blueprint(users_bp, url_prefix='/api/users')
    app.register_blueprint(roles_bp, url_prefix='/api/roles')
    app.register_blueprint(permissions_bp, url_prefix='/api/permissions')
    app.register_blueprint(menus_bp, url_prefix='/api/menus')
    app.register_blueprint(stats_bp, url_prefix='/api/stats')
    app.register_blueprint(regulation_services_bp, url_prefix='/api/regulation-services')
    app.register_blueprint(gep_parameters_bp, url_prefix='/api/gep-parameters')
    app.register_blueprint(gep_results_bp, url_prefix='/api/gep-results')
    app.register_blueprint(vep_parameters_bp, url_prefix='/api/vep-parameters')
    app.register_blueprint(vep_results_bp, url_prefix='/api/vep-results')
    
    # 导入模型以确保表被创建
    from app.models import User, Role, Permission, Menu, UserRole, RolePermission, RoleMenu
    
    # 错误处理
    @app.errorhandler(404)
    def not_found(error):
        return {'message': '资源不存在'}, 404
    
    @app.errorhandler(500)
    def internal_error(error):
        return {'message': '服务器内部错误'}, 500
    
    # 数据库连接错误处理
    @app.errorhandler(Exception)
    def handle_exception(e):
        if 'Lost connection to MySQL server' in str(e):
            print(f"❌ 数据库连接丢失: {e}")
            return {'message': '数据库连接暂时不可用，请稍后重试'}, 503
        elif 'OperationalError' in str(e):
            print(f"❌ 数据库操作错误: {e}")
            return {'message': '数据库操作失败，请稍后重试'}, 503
        else:
            print(f"❌ 未处理的异常: {e}")
            return {'message': '服务器内部错误'}, 500
    
    return app 